Macros with Variable Numbers of Arguments

Contents|Index|Previous|Next
Macros with variable numbers of arguments

In GNU C, a macro can accept a variable number of arguments, much as a function can. The syntax for defining the macro looks much like that used for a function. The following is an example.

    #define eprintf(format, args...)       \
     fprintf (stderr, format , ## args)

args is a rest argument: it takes in zero or more arguments, as many as the call contains. All of them plus the commas between them form the value of args, which is substituted into the macro body where args is used. Thus, we have the following expansion.

    eprintf ("%s:%d: ", input_file_name, line_number)
    å
    fprintf (stderr, "%s:%d: ", input_file_name, line_number)

Note:
The comma after the string constant comes from the definition of eprintf, whereas the last comma comes from the value of args.

The reason for using ‘##’ is to handle the case when args matches no arguments at all. In this case, args has an empty value. In this case, the second comma in the definition becomes an embarrassment: if it got through to the expansion of the macro, we would get something like the following.

    fprintf (stderr, "success!\n" , )

The previous example shows invalid C syntax. ‘##’ gets rid of the comma, so, instead, we get the following.

    fprintf (stderr, "success!\n")

This is a special feature of the GNU C preprocessor: ‘##’ before a rest argument that is empty discards the preceding sequence of non-whitespace characters from the macro definition. (If another macro argument precedes, none of it is discarded.)

It might be better to discard the last preprocessor token instead of the last preceding sequence of non-whitespace characters; in fact, we may someday change this feature to do so. We advise you to write the macro definition so that the preceding sequence of non-whitespace characters is just a single token, so that the meaning will not change if we change the definition of this feature.

Top|Contents|Index|Previous|Next